package com.hailiao.beidou.message.ui.page.connect

import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.navigationBarsPadding
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import com.d10ng.compose.ui.AppColor
import com.d10ng.compose.ui.AppText
import com.d10ng.compose.ui.PageTransitions
import com.d10ng.compose.ui.base.Cell
import com.d10ng.compose.ui.base.CellGroup
import com.d10ng.compose.ui.base.CellRow
import com.d10ng.compose.ui.form.Checkbox
import com.d10ng.compose.ui.form.Field
import com.d10ng.compose.ui.navigation.NavBar
import com.d10ng.compose.ui.show.Tag
import com.hailiao.beidou.comm.serialport.SPDeviceManager
import com.hailiao.beidou.message.bd.sp.SPMode
import com.hailiao.beidou.message.data.store.data.SPSettingData
import com.hailiao.beidou.message.utils.back
import com.ramcosta.composedestinations.annotation.Destination
import com.ramcosta.composedestinations.annotation.RootNavGraph

/**
 * 串口连接配置页
 * @Author d10ng
 * @Date 2024/3/7 10:29
 */
@RootNavGraph
@Destination(style = PageTransitions::class)
@Composable
fun SPConnectScreen(
    model: SPConnectScreenViewModel = viewModel()
) {
    val mode by model.modeFlow.collectAsState()
    val setting by model.settingFlow.collectAsState()
    SPConnectScreenView(
        mode = mode,
        setting = setting,
        onChangeMode = model::onChangeMode,
        onChangeSetting = model::onUpdateSetting,
        onClickBaudRate = model::onClickBaudRate,
        onClickDataBits = model::onClickDataBits,
        onClickParity = model::onClickParity,
        onClickStopBits = model::onClickStopBits,
        onClickOpen = model::onClickOpen
    )
}

@Composable
private fun SPConnectScreenView(
    mode: SPMode = SPMode.CUSTOM,
    setting: SPSettingData = SPSettingData(),
    onChangeMode: (SPMode) -> Unit = {},
    onChangeSetting: (SPSettingData) -> Unit = {},
    onClickBaudRate: () -> Unit = {},
    onClickDataBits: () -> Unit = {},
    onClickParity: () -> Unit = {},
    onClickStopBits: () -> Unit = {},
    onClickOpen: () -> Unit = {}
) {
    Column(
        modifier = Modifier
            .fillMaxSize()
            .background(AppColor.Neutral.bg)
            .navigationBarsPadding()
    ) {
        NavBar(
            title = "串口终端连接",
            titleAlignment = Alignment.CenterStart,
            onClickBack = { back() }
        )
        Column(
            modifier = Modifier
                .fillMaxSize()
                .weight(1f)
                .verticalScroll(rememberScrollState())
        ) {
            CellGroup(title = "配置模版", border = false) {
                SPMode.entries.forEach { item ->
                    CellRow(
                        contentPaddingValues = PaddingValues(vertical = 16.dp, horizontal = 19.dp)
                    ) {
                        Text(text = item.text, style = AppText.Normal.Body.default)
                        Spacer(modifier = Modifier.weight(1f))
                        if (item.wire != null && item.wire == SPDeviceManager.getType()) {
                            Tag(text = "推荐")
                        }
                        Checkbox(
                            checked = item == mode,
                            onCheckedChange = { onChangeMode(item) },
                            modifier = Modifier.padding(start = 16.dp)
                        )
                    }
                }
            }
            if (mode == SPMode.CUSTOM) {
                CellGroup(title = "自定义配置", border = false) {
                    Field(
                        value = setting.rdPath,
                        onValueChange = { onChangeSetting(setting.copy(rdPath = it.trim())) },
                        label = "串口地址",
                        canClear = true
                    )
                    Cell(
                        title = "波特率",
                        value = setting.rdBaudRate.intValue.toString(),
                        link = true,
                        onClick = onClickBaudRate
                    )
                    Cell(
                        title = "数据位",
                        value = setting.rdDataBits.intValue.toString(),
                        link = true,
                        onClick = onClickDataBits
                    )
                    Cell(
                        title = "校验位",
                        value = setting.rdParity.char.toString(),
                        link = true,
                        onClick = onClickParity
                    )
                    Cell(
                        title = "停止位",
                        value = setting.rdStopBits.intValue.toString(),
                        link = true,
                        onClick = onClickStopBits
                    )
                }
            }
        }
        Box(
            modifier = Modifier
                .fillMaxWidth()
                .height(62.dp)
                .background(AppColor.Main.primary)
                .clickable { onClickOpen() },
            contentAlignment = Alignment.Center
        ) {
            Text(
                text = "打开串口",
                style = AppText.Normal.White.big
            )
        }
    }
}

@Preview
@Composable
private fun SPConnectScreenPreview() {
    SPConnectScreenView()
}